#include "part_die.h"
#include "part2d.h"
#include "part_group.h"
#include "particle_2d.h"

#include "math/vec2.h"

#include "num/rand.h"

#include "script/scripthelper.h"

#include "util/log.h"		    // log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    // Needs to come in early

#include <cassert>
#include <stdlib.h>

using namespace part2d;







class PartDieDirection : public PartDie
{
public:
	PartDieDirection(Part2D* pBase, int GroupID, int Probability) : PartDie(pBase, GroupID, Probability) {};
	virtual	void		ParticleDie(Particle2D* pPart)
	{
		assert(pPart && m_pBaseSys);
		if (!IsProbable()) return;
		PartGroup* pGroup = m_pBaseSys->GetGroup(m_GroupID);
		if (pGroup)
		{
			math::Vec2	Speed = pGroup->GetInitialSpeed();
			math::Vec2	Dir =	(pPart->Dir * -Speed.y * pPart->Speed) + 
								(math::Vec2(pPart->Dir.y, -pPart->Dir.x) * Speed.x * pPart->Speed);
			pGroup->TriggerParticle(pPart->Pos, Dir);
		}
	};
	virtual std::string	GetName() const { return "part_direction"; };
};



//////////////////////////////////
// base
PartDie*	PartDie::GetPartDie(LuaPlus::LuaObject Obj, part2d::Part2D* pBase)
{
	if (!Obj.IsTable()) return NULL;
	std::string	Name		= 	script::ScriptHelper::GetTableString(Obj, "Type", "part_rebirth");
	int			GroupID		=	script::ScriptHelper::GetTableInt(Obj, "Group", 0);
	float		Probability =	script::ScriptHelper::GetTableFloat(Obj, "Probability", 1.0f) * 100;
	if (strcmpi(Name.c_str(), "part_rebirth")==0) return new PartDie(pBase, GroupID, (int)Probability);
	if (strcmpi(Name.c_str(), "part_direction")==0) return new PartDieDirection(pBase, GroupID, (int)Probability);
	return NULL;
}

PartDie*	PartDie::GetPartDie(PartDie* pPartDie, Part2D* pBase)
{
	std::string Name = pPartDie->GetName();
	int GroupID = pPartDie->m_GroupID;
	int Probability = pPartDie->m_Probability;

	if (strcmpi(Name.c_str(), "part_rebirth")==0) return new PartDie(pBase, GroupID, Probability);
	if (strcmpi(Name.c_str(), "part_direction")==0) return new PartDieDirection(pBase, GroupID, Probability);
	return NULL;
}


PartDie::PartDie(Part2D* pBase, int GroupID, int Probability) :
	m_pBaseSys(pBase),
	m_GroupID(GroupID),
	m_Probability(Probability)
{
	assert(pBase);
}

PartDie::~PartDie()
{

}

bool	PartDie::IsProbable()
{
	if (m_Probability >= 100) return true;
	return (m_Probability > (rand() % 100));
}
void	PartDie::ParticleDie(Particle2D* pPart)
{
	assert(pPart && m_pBaseSys);
	if (!IsProbable()) return;
	PartGroup* pGroup = m_pBaseSys->GetGroup(m_GroupID);
	if (pGroup)
	{
		pGroup->TriggerParticle(pPart->Pos);
	}
}

